home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / cap / ogl_shapes.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  9KB  |  362 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <math.h>
  19. #include <GL/gl.h>
  20. #include <GL/glu.h>
  21. #include "ogl_shapes.h"
  22.  
  23. #define TORUSWIRE    0
  24. #define TORUSSOLID    1
  25. #define CUBEWIRE    2
  26. #define CUBESOLID   3
  27. #define NUM_LISTS   4
  28.  
  29. #define STACKDEPTH 10
  30. #define ADD_QUAD 1
  31. #define PI     3.1415926535897
  32.  
  33. typedef struct {
  34.     float   mat[4][4];
  35.     float   norm[3][3];
  36. } mat_t;
  37.  
  38. static mat_t matstack[STACKDEPTH] = {
  39.     {{
  40.         {1.0, 0.0, 0.0, 0.0},
  41.         {0.0, 1.0, 0.0, 0.0},
  42.         {0.0, 0.0, 1.0, 0.0},
  43.         {0.0, 0.0, 0.0, 1.0}
  44.     },
  45.  
  46.     {
  47.         {1.0, 0.0, 0.0},
  48.         {0.0, 1.0, 0.0},
  49.         {0.0, 0.0, 1.0}
  50.     }
  51. }
  52. };
  53. static long identitymat = 1;
  54.  
  55. static long mattop = 0;
  56.  
  57. static GLuint lists[NUM_LISTS] = { 0, 0, 0, 0 };
  58.  
  59. static GLvoid 
  60. normalize(GLfloat v[3])
  61. {
  62.     float d;
  63.  
  64.     d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
  65.     if (d == 0.0) {
  66.         fprintf(stderr, "normalize: zero length vector\n");
  67.         v[0] = d = 1.0;
  68.     }
  69.     d = 1/d;
  70.     v[0] *= d;
  71.     v[1] *= d;
  72.     v[2] *= d;
  73. }
  74.  
  75. static void 
  76. m_xformpt(GLfloat pin[3], GLfloat pout[3], 
  77.           GLfloat nin[3], GLfloat nout[3])
  78. {
  79.     long    i;
  80.     float   ptemp[3], ntemp[3];
  81.     mat_t   *m = &matstack[mattop];
  82.  
  83.     if (identitymat) {
  84.         for (i = 0; i < 3; i++) {
  85.             pout[i] = pin[i];
  86.             nout[i] = nin[i];
  87.         }
  88.         return;
  89.     }
  90.     for (i = 0; i < 3; i++) {
  91.         ptemp[i] = pin[0]*m->mat[0][i] +
  92.             pin[1]*m->mat[1][i] +
  93.             pin[2]*m->mat[2][i] +
  94.             m->mat[3][i];
  95.         ntemp[i] = nin[0]*m->norm[0][i] +
  96.             nin[1]*m->norm[1][i] +
  97.             nin[2]*m->norm[2][i];
  98.     }
  99.     for (i = 0; i < 3; i++) {
  100.         pout[i] = ptemp[i];
  101.         nout[i] = ntemp[i];
  102.     }
  103.     normalize(nout);
  104. }
  105.  
  106. static GLvoid 
  107. doughnut(GLfloat r, GLfloat R, long nsides, long rings, 
  108.          GLvoid (*savefunc)())
  109. {
  110.     long    i, j;
  111.     float   theta, phi, theta1, phi1;
  112.     float   p0[03], p1[3], p2[3], p3[3];
  113.     float   n0[3], n1[3], n2[3], n3[3];
  114.     float   t0[2], t1[2], t2[2], t3[2];
  115.  
  116.     for (i = 0; i < rings; i++) {
  117.         theta = (float)i*2.0*PI/rings;
  118.         theta1 = (float)(i+1)*2.0*PI/rings;
  119.         for (j = 0; j < nsides; j++) {
  120.             phi = (float)j*2.0*PI/nsides;
  121.             phi1 = (float)(j+1)*2.0*PI/nsides;
  122.  
  123.             t0[0] = ((float)i)/((float)rings);
  124.             t0[1] = ((float)j)/((float)nsides);
  125.  
  126.             t1[0] = ((float)i+1)/((float)rings);
  127.             t1[1] = ((float)j)/((float)nsides);
  128.  
  129.             t2[0] = ((float)i+1)/((float)rings);
  130.             t2[1] = ((float)j+1)/((float)nsides);
  131.  
  132.             t3[0] = ((float)i)/((float)rings);
  133.             t3[1] = ((float)j+1)/((float)nsides);
  134.  
  135.             p0[0] = cos(theta)*(R + r*cos(phi));
  136.             p0[1] = -sin(theta)*(R + r*cos(phi));
  137.             p0[2] = r*sin(phi);
  138.  
  139.             p1[0] = cos(theta1)*(R + r*cos(phi));
  140.             p1[1] = -sin(theta1)*(R + r*cos(phi));
  141.             p1[2] = r*sin(phi);
  142.  
  143.             p2[0] = cos(theta1)*(R + r*cos(phi1));
  144.             p2[1] = -sin(theta1)*(R + r*cos(phi1));
  145.             p2[2] = r*sin(phi1);
  146.  
  147.             p3[0] = cos(theta)*(R + r*cos(phi1));
  148.             p3[1] = -sin(theta)*(R + r*cos(phi1));
  149.             p3[2] = r*sin(phi1);
  150.  
  151.             n0[0] = cos(theta)*(cos(phi));
  152.             n0[1] = -sin(theta)*(cos(phi));
  153.             n0[2] = sin(phi);
  154.  
  155.             n1[0] = cos(theta1)*(cos(phi));
  156.             n1[1] = -sin(theta1)*(cos(phi));
  157.             n1[2] = sin(phi);
  158.  
  159.             n2[0] = cos(theta1)*(cos(phi1));
  160.             n2[1] = -sin(theta1)*(cos(phi1));
  161.             n2[2] = sin(phi1);
  162.  
  163.             n3[0] = cos(theta)*(cos(phi1));
  164.             n3[1] = -sin(theta)*(cos(phi1));
  165.             n3[2] = sin(phi1);
  166.  
  167.             m_xformpt(p0, p0, n0, n0);
  168.             m_xformpt(p1, p1, n1, n1);
  169.             m_xformpt(p2, p2, n2, n2);
  170.             m_xformpt(p3, p3, n3, n3);
  171.  
  172.             (*savefunc)(ADD_QUAD, n3, t3, p3, n2, t2, p2, n1, t1, p1, n0, t0, p0);
  173.         }
  174.     }
  175. }
  176.  
  177. static void 
  178. drawbox(float x0, float x1, float y0, float y1, 
  179.         float z0, float z1, void (*savefunc)())
  180. {
  181.     long    i;
  182.     float   temp;
  183.     float   p0[3], p1[3], p2[3], p3[3];
  184.     float   n0[3], n1[3], n2[3], n3[3];
  185.     float   t0[2], t1[2], t2[2], t3[2];
  186.     float cv[8][3];
  187.     float cnorms[6][3] = {
  188.         {-1.0, 0.0, 0.0},
  189.         {0.0, 1.0, 0.0},
  190.         {1.0, 0.0, 0.0},
  191.         {0.0, -1.0, 0.0},
  192.         {0.0, 0.0, 1.0},
  193.         {0.0, 0.0, -1.0}
  194.         };
  195.     long faces[6][4] = {
  196.         { 0, 1, 2, 3 },
  197.         { 3, 2, 6, 7 },
  198.         { 7, 6, 5, 4 },
  199.         { 4, 5, 1, 0 },
  200.         { 5, 6, 2, 1 },
  201.         { 7, 4, 0, 3 }
  202.     };
  203.  
  204.  
  205.  
  206.     if (x0 > x1) {
  207.         temp = x0;
  208.         x0 = x1;
  209.         x1 = temp;
  210.     }
  211.     if (y0 > y1) {
  212.         temp = y0;
  213.         y0 = y1;
  214.         y1 = temp;
  215.     }
  216.     if (z0 > z1) {
  217.         temp = z0;
  218.         z0 = z1;
  219.         z1 = temp;
  220.     }
  221.     cv[0][0] = cv[1][0] = cv[2][0] = cv[3][0] = x0;
  222.     cv[4][0] = cv[5][0] = cv[6][0] = cv[7][0] = x1;
  223.     cv[0][1] = cv[1][1] = cv[4][1] = cv[5][1] = y0;
  224.     cv[2][1] = cv[3][1] = cv[6][1] = cv[7][1] = y1;
  225.     cv[0][2] = cv[3][2] = cv[4][2] = cv[7][2] = z0;
  226.     cv[1][2] = cv[2][2] = cv[5][2] = cv[6][2] = z1;
  227.     t0[0] = 0.0;
  228.     t0[1] = 0.0;
  229.     t1[0] = 0.0;
  230.     t1[1] = 1.0;
  231.     t2[0] = 1.0;
  232.     t2[1] = 1.0;
  233.     t3[0] = 1.0;
  234.     t3[1] = 0.0;
  235.     for (i = 0; i < 6; i++) {
  236.         m_xformpt(&cv[faces[i][0]][0], p0, &cnorms[i][0], n0);
  237.         m_xformpt(&cv[faces[i][1]][0], p1, &cnorms[i][0], n1);
  238.         m_xformpt(&cv[faces[i][2]][0], p2, &cnorms[i][0], n2);
  239.         m_xformpt(&cv[faces[i][3]][0], p3, &cnorms[i][0], n3);
  240.         (*savefunc)(ADD_QUAD, n0, t0, p0, n1, t1, p1, n2, t2, p2, n3, t3, p3);
  241.     }
  242. }
  243.  
  244. static GLvoid 
  245. savequad(long type, 
  246.          GLfloat * n0, GLfloat * t0, GLfloat * v0, 
  247.          GLfloat * n1, GLfloat * t1, GLfloat * v1, 
  248.          GLfloat * n2, GLfloat * t2, GLfloat * v2, 
  249.          GLfloat * n3, GLfloat * t3, GLfloat * v3)
  250. {
  251.     glBegin (GL_POLYGON);
  252.     glNormal3fv(n0);
  253.     glVertex3fv(v0);
  254.     glNormal3fv(n1);
  255.     glVertex3fv(v1);
  256.     glNormal3fv(n2);
  257.     glVertex3fv(v2);
  258.     glNormal3fv(n3);
  259.     glVertex3fv(v3);
  260.     glEnd();
  261. }
  262.  
  263. static GLvoid 
  264. savewirequad(long type, 
  265.              GLfloat * n0, GLfloat * t0, GLfloat * v0, 
  266.              GLfloat * n1, GLfloat * t1, GLfloat * v1, 
  267.              GLfloat * n2, GLfloat * t2, GLfloat * v2, 
  268.              GLfloat * n3, GLfloat * t3, GLfloat * v3)
  269. {
  270.     glBegin (GL_LINE_LOOP);
  271.     glNormal3fv(n0);
  272.     glVertex3fv(v0);
  273.     glNormal3fv(n1);
  274.     glVertex3fv(v1);
  275.     glNormal3fv(n2);
  276.     glVertex3fv(v2);
  277.     glNormal3fv(n3);
  278.     glVertex3fv(v3);
  279.     glEnd();
  280. }
  281.  
  282. /*  Create display lists for rendering torii.        */
  283.  
  284. static GLvoid 
  285. wireTorus (GLvoid)
  286. {
  287.     lists[TORUSWIRE] = glGenLists (1);
  288.     glNewList(lists[TORUSWIRE], GL_COMPILE);
  289.     doughnut(0.25, 0.75, 5, 10, savewirequad);
  290.     glEndList();
  291. }
  292.  
  293. static GLvoid 
  294. solidTorus (GLvoid)
  295. {
  296.     lists[TORUSSOLID] = glGenLists (1);
  297.     glNewList(lists[TORUSSOLID], GL_COMPILE);
  298.     doughnut(0.25, 0.75, 8, 15, savequad);
  299.     glEndList();
  300. }
  301. static GLvoid
  302. wireCube (GLvoid)
  303. {
  304.     lists[CUBEWIRE] = glGenLists (1);
  305.     glNewList(lists[CUBEWIRE], GL_COMPILE);
  306.     drawbox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, savewirequad);
  307.     glEndList();
  308. }
  309.  
  310. static GLvoid
  311. solidCube (GLvoid)
  312. {
  313.     lists[CUBESOLID] = glGenLists (1);
  314.     glNewList(lists[CUBESOLID], GL_COMPILE);
  315.     drawbox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, savequad);
  316.     glEndList();
  317. }
  318.  
  319. /*  Render the appropriate display lists for the torii.    */
  320.  
  321. GLvoid 
  322. doWireTorus (void)
  323. {
  324.     if (glIsList(lists[TORUSWIRE]) == 0)
  325.         wireTorus ();
  326.     glCallList(lists[TORUSWIRE]);
  327. }
  328.  
  329. GLvoid 
  330. doSolidTorus (void)
  331. {
  332.     if (glIsList(lists[TORUSSOLID]) == 0)
  333.         solidTorus ();
  334.     glCallList(lists[TORUSSOLID]);
  335. }
  336.  
  337. GLvoid
  338. doWireCube (void)
  339. {
  340.     if (glIsList(lists[CUBEWIRE]) == 0)
  341.         wireCube ();
  342.     glCallList(lists[CUBEWIRE]);
  343. }
  344.  
  345. GLvoid
  346. doSolidCube (void)
  347. {
  348.     if (glIsList(lists[CUBESOLID]) == 0)
  349.         solidCube ();
  350.     glCallList(lists[CUBESOLID]);
  351. }
  352.  
  353. GLvoid
  354. initStockShapes (GLvoid)
  355. {
  356.     wireTorus();
  357.     solidTorus();
  358.     wireCube();
  359.     solidCube();
  360. }
  361.  
  362.